package com.bootcamp.javase2.synchro;

/**
 * @program: day20Sycn
 * @description: use two threads and wait, notify method to print even and odd.
 * @author: Keyu Li
 * @create: 2021-09-14 19:49
 **/

public class PrintEvenOdd {
    public static void main(String[] args) {
        MonitorObject mon = new MonitorObject();
        new Thread(new PrintOdd(mon), "ThreadOdd").start();
        new Thread(new PrintEven(mon), "ThreadEven").start();
    }
}

class PrintOdd implements Runnable {
    MonitorObject mon;

    public PrintOdd(MonitorObject mon) {
        this.mon = mon;
    }

    @Override
    public void run() {
        synchronized (mon) {
            int index;
            while ((index = mon.getIndex()) <= 100) {
                if (index % 2 == 1) {
                    // when index is odd, print it and notify printeven
                    System.out.println(Thread.currentThread().getName() + "----" + index);
                    mon.setIndex(index + 1);
                    mon.notify();
                } else {
                    // when index is even, printeven working, this thread wait.
                    try {
                        mon.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

class PrintEven implements Runnable {
    MonitorObject mon;

    public PrintEven(MonitorObject mon) {
        this.mon = mon;
    }

    @Override
    public void run() {
        synchronized (mon) {
            int index;
            while ((index = mon.getIndex()) <= 100) {
                if (mon.getIndex() % 2 == 1) {
                    // when index is odd, printodd working, wait
                    try {
                        mon.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                } else {
                    // when index is even, print it and notify printodd
                    System.out.println(Thread.currentThread().getName() + "----" + index);
                    mon.setIndex(index + 1);
                    mon.notify();
                }
            }
        }
    }
}


class MonitorObject {
    // store the current number
    int index = 1;

    public void setIndex(int index) {
        this.index = index;
    }

    public int getIndex() {
        return index;
    }
}
